#! /bin/sh -
# Copyright (C) 2024-2025 KoudaiPC Computer Technologies Co., Ltd.
# script name: bootstrap.sh
# author: david921518@qq.com

################
# environment variables
. /etc/profile
export LANG=C
################

if [ ! -f /usr/lib/kpc/posix-arrays.sh ]; then
  mkdir -p /usr/lib/kpc
  wget https://gitee.com/m8t/kpcos/raw/master/distro/huangdi/tools/posix-arrays.sh -O /usr/lib/kpc/posix-array.sh
fi

if [ ! -f /usr/lib/kpc/posix-arrays.sh ]; then
  echo "Please download posix-arrays.sh with command:"
  echo "  mkdir -p /usr/lib/kpc"
  echo "  wget https://gitee.com/m8t/kpcos/raw/master/distro/huangdi/tools/posix-arrays.sh -O /usr/lib/kpc/posix-array.sh"
  exit 1
fi

. /usr/lib/kpc/posix-arrays.sh

################
# global vars
GLB_WORK_DIR=
GLB_DONE_FILE=
GLB_OW_TARGET=
GLB_OW_VER=
GLB_HD_VER=
GLB_HD_NEXT_VER=
GLB_ROOT_DEV=
GLB_ROOT_PART=
GLB_ROOT_DISK=
GLB_ROOT_PART_NUM=
GLB_REBOOT_COUNTER=
#GLB_INSTALLED_PKGS=()
declare_i_arr GLB_INSTALLED_PKGS
GLB_NUM_INSTALLED_PKGS=0
GLB_BOOTSTRAP_WORK_DIR=/etc/kpc
GLB_BOOTSTRAP_FILE=$GLB_BOOTSTRAP_WORK_DIR/bootstrap.sh
GLB_UPGRADE_FILE=$GLB_BOOTSTRAP_WORK_DIR/upgrade.sh
GLB_TESTING_FILE=$GLB_BOOTSTRAP_WORK_DIR/testing.sh
GLB_REAL_PATH=
################

whoami=$(which whoami)
if [ x"$whoami" == x ]; then
  user="$USER"
else
  user=$(whoami)
fi

function run_clean()
{
  rm -rf bootstrap
  rm -rf bootstrap.tgz
  rm -rf bootstrap.tgz.md5
  rm -rf bootstrap.tgz.sha256
  rm -rf bootstrap.tgz.sha512
  rm -rf bootstrap.sh_done
  rm -rf reboot_counter
  rm -rf pre_bootstrap_pkgs.txt
  rm -rf post_bootstrap_pkgs.txt
  rm -rf upgrade.tgz
  rm -rf upgrade.tgz.md5
  rm -rf upgrade.tgz.sha256
  rm -rf upgrade.tgz.sha512
}

inst_type="bootstrap"
case "$inst_type" in
  bootstrap )
    echo "run_first_boot"
    #run_first_boot
    ;;
  upgrade )
    echo "run_sys_upgrade"
    #run_sys_upgrade
    ;;
  testing )
    echo "run_sys_upgrade with testing"
    #run_sys_upgrade
    ;;
  install )
    echo "run_install with type=[$1]"
    #run_install $1
    inst_type="$1"
    if [ "$inst_type" == "clean" ]; then
      echo "run_clean"
      run_clean
      exit 0
    fi
    ;;
  clean )
    echo "run_clean"
    run_clean
    exit 0
    ;;
  * )
    echo "usage: $0 [bootstrap|upgrade|testing|clean]"
    exit 0
    ;;
esac

log_kmsg_path="/dev/kmsg"
log_con_path="/dev/tty1"
log_file_name="${inst_type}.log"

# 定义日志格式-前缀
log_prefix="[$inst_type]"
# 定义日志目录和文件名
if [ "$user" == "root" ]; then
  log_file_dir="/var/log/kpc/huangdi"
else
  log_file_dir=~/.local/log/kpc/huangdi
fi
log_file_path="$log_file_dir/$log_file_name"

function log_init()
{
  # 文件不存在则创建
  if [ ! -d "$log_file_dir" ]; then
    mkdir -p $log_file_dir
    chmod -R 755 $log_file_dir
  fi
  if [ ! -f "$log_file_path" ]; then
    touch $log_file_path
  fi
}

# 定义日志打印格式
function log()
{
  # 定义日志时间格式
  local curtime=$(date "+%Y-%m-%d %H:%M:%S")
  echo "$curtime $log_prefix $@"
  echo "$curtime $log_prefix $@" >> $log_file_path
  #sleep 1
  if [ "$user" == "root" ]; then
    echo "$log_prefix [kmsg] $@" > $log_kmsg_path
    sleep 1
    #echo "$curtime $log_prefix [con] $@" > $log_con_path
    #sleep 1
  fi
}

function log_from_file()
{
  tmpfile=$@
  if [ ! -f "$tmpfile" ]; then
    log "no file [$tmpfile] to log"
    return 1
  fi

  declare_i_arr lists
  while IFS= read -r line;
  do
    add_i_arr_el lists "$line"
  done <$tmpfile

  # 定义日志时间格式
  local curtime=$(date "+%Y-%m-%d %H:%M:%S")

  #echo "$curtime $log_prefix $@"
  #echo "$curtime $log_prefix $@" >>$log_file_path
  local i=0
  get_i_arr_indices lists indices
  for i in $indices
  do
    echo "$curtime $log_prefix ${line}"
    echo "$curtime $log_prefix ${line}" >>$log_file_path
  done

  if [ "$user" == "root" ]; then
    #echo "$log_prefix [kmsg] $@" >$log_kmsg_path
    get_i_arr_indices lists indices
    for i in $indices
    do
      echo "$curtime $log_prefix ${line}" >$log_kmsg_path
      [ $(( i%10 )) -ne 9 ] || sleep 1
    done

    #sleep 1

    #echo "$curtime $log_prefix [con] $@" >$log_con_path
    #for i in $( seq 0 $((${#lists[*]} - 1)) )
    #do
    #  echo "$curtime $log_prefix ${lists[i]}" >$log_con_path
    #done

    #sleep 1
  fi
}

# loop forever to reboot
function force_reboot()
{
  log "force reboot now!"
  while true; do reboot; sleep 9; done
}

# fix all kinds of possible broken issues
function fix_possible_broken()
{
  #log "do nothing!!!"
  local is_opkg=$(which opkg)
  if [ x"$is_opkg" == x ]; then
    log "Not ipk package managing system!!!"
  else
    opkg update
    # base tools
    opkg install coreutils-whoami
    opkg install coreutils-realpath
    opkg install curl
    # manipulate partition tools
    opkg install parted
    opkg install losetup
    opkg install resize2fs
    opkg install blkid
    opkg install lsblk
  fi
}

# get Work Dir
function get_work_dir()
{
  ################
  # /root/bootstrap.sh
  # /root/firstboot/guest/huangdi-first-boot.sh
  # /root/firstboot/root/etc/zzz-firstboot
  # /root/upgrade/guest/huangdi-sys-upgrade.sh
  # /root/upgrade/root/etc/zzz-sysupgrade
  ################

  local real_path=$(realpath $0)
  GLB_REAL_PATH="$real_path"
  log "REAL PATH is [$GLB_REAL_PATH]"

  GLB_WORK_DIR=$(dirname "$real_path")
  log "WORK DIR is [$GLB_WORK_DIR]"

  local done_file="${real_path}_done"
  log "done_file=[$done_file]"
  real_done_file=$(realpath "$done_file")
  log "real_done_file=[$real_done_file]"

  GLB_DONE_FILE="$real_done_file"
  log "GLB_DONE_FILE=[$GLB_DONE_FILE]"

  GLB_REBOOT_COUNTER=$GLB_WORK_DIR/reboot_counter
  log "GLB_REBOOT_COUNTER=$GLB_REBOOT_COUNTER"
  if [ ! -f $GLB_REBOOT_COUNTER ]; then
    echo "0" >$GLB_REBOOT_COUNTER
  fi
}

function check_reboot_counter()
{
  local reboot_counter=$(cat $GLB_REBOOT_COUNTER)
  reboot_counter=$((reboot_counter + 1))
  log "reboot counter is [$reboot_counter]"
  if [ $reboot_counter -gt 9 ]; then
    log "reboot too many times, exit now!"
    exit 1
  else
    log "set reboot counter to [$reboot_counter]"
    echo "$reboot_counter" >$GLB_REBOOT_COUNTER
  fi
}

function reset_reboot_counter()
{
  log "reset reboot counter"
  echo "0" >$GLB_REBOOT_COUNTER
}

# save installed packages list
function save_pkg_list()
{
  if [ "$1" == "" ]; then
    log "save_pkg_list() filename is empty, do nothing!"
    return
  fi
  local list_file="$PWD"/$1
  log "save $inst_type packages list to $list_file"
  [ -f $list_file ] || opkg list-installed >$list_file
}

# detect CPU Arch
function detect_cpu_arch()
{
  local cpu_arch=$(lscpu | grep "Architecture:" | awk '{print $2}')
  case "$cpu_arch" in
    x86_64 )
      GLB_OW_TARGET="x86/64"
      ;;
    aarch64 )
      GLB_OW_TARGET="armsr/armv8"
      ;;
    * )
      log "Unknown CPU Arch [$cpu_arch], exit now!"
      #force_reboot
      exit 1
      ;;
  esac
  log "CPU Arch [$cpu_arch] is OpenWrt target [$GLB_OW_TARGET]"
}

function get_openwrt_version_string()
{
  ow_release_file=$1
  if [ ! -f $ow_release_file ]; then
    log "No openwrt release file $ow_release_file"
    force_reboot
  fi
  local tmp_var=$(grep "DISTRIB_RELEASE=" $ow_release_file | awk '{split($0,a,"="); print a[2]}')

  if [ "${tmp_var#\"}" != "$tmp_var" ]; then
    unquoted_str=$(echo "$tmp_var" | sed -e 's/^"//' -e 's/"$//')
  elif [ "${tmp_var#\'}" != "$tmp_var" ]; then
    unquoted_str=$(echo "$tmp_var" | sed -e "s/^'//" -e "s/'$//")
  else
    unquoted_str=$tmp_var
  fi
  echo "$unquoted_str"
}

# find OpenWrt Version to set HuangDi Version
function find_openwrt_version()
{
  ow_release_file=$1
  if [ ! -f $ow_release_file ]; then
    log "No openwrt release file $ow_release_file"
    force_reboot
  fi
  local latest_ow_2305_hd_ver=0.56
  local latest_ow_2410_hd_ver=1.04
  local latest_ow_snapshot_hd_ver=1.5
  local tmp_var=$(grep "DISTRIB_RELEASE=" $ow_release_file | awk '{split($0,a,"="); print a[2]}')

  if [ "${tmp_var#\"}" != "$tmp_var" ]; then
    unquoted_str=$(echo "$tmp_var" | sed -e 's/^"//' -e 's/"$//')
  elif [ "${tmp_var#\'}" != "$tmp_var" ]; then
    unquoted_str=$(echo "$tmp_var" | sed -e "s/^'//" -e "s/'$//")
  else
    unquoted_str=$tmp_var
  fi
  log "unquoted_str=[$unquoted_str]"
  local ow_ver=$unquoted_str
  log "ow_ver=[$ow_ver]"
  case "$ow_ver" in
    "25.10."* )
      #GLB_HD_VER=1.5x
      GLB_HD_VER=$latest_ow_snapshot_hd_ver
      GLB_HD_NEXT_VER=
      if [ "$inst_type" == "upgrade"]; then
        log "Unsupported OpenWrt Version [$ow_ver], exit now!"
        #force_reboot
        exit 1
      fi
      ;;
    "24.10."* )
      #GLB_HD_VER=1.0x
      GLB_HD_VER=$latest_ow_2410_hd_ver
      GLB_HD_NEXT_VER=$latest_ow_snapshot_hd_ver
      ;;
    "23.05."* )
      #GLB_HD_VER=0.5x
      GLB_HD_VER=$latest_ow_2305_hd_ver
      GLB_HD_NEXT_VER=$latest_ow_2410_hd_ver
      ;;
    * )
      log "Unsupported OpenWrt Version [$ow_ver], exit now!"
      #force_reboot
      exit 1
      ;;
  esac
  GLB_OW_VER="$ow_ver"
  log "OpenWrt Version [$GLB_OW_VER] is HuangDi Version [$GLB_HD_VER]"
  log "Next HuangDi Version is [$GLB_HD_NEXT_VER]"
}

function verify_upgrade_version()
{
  if [ "$inst_type" == "upgrade" ]; then
    if [ x"$GLB_HD_NEXT_VER" == x ]; then
      log "No upgrade version for HuangDi version [$GLB_HD_VER]"
      exit 1
    fi
  fi
}

# get ROOT device from /proc/self/mountinfo
function simple_get_root_dev()
{
  ROOT_BLK="$(readlink -f /sys/dev/block/"$(awk -e \
    '$9=="/dev/root"{print $3}' /proc/self/mountinfo)")"
  GLB_ROOT_DISK="/dev/$(basename "${ROOT_BLK%/*}")"
  GLB_ROOT_PART="/dev/${ROOT_BLK##*/}"
  GLB_ROOT_PART_NUM="${ROOT_BLK##*[^0-9]}"
  GLB_ROOT_DEV="$GLB_ROOT_DISK"
  #GLB_ROOT_PART="${GLB_ROOT_DEV}${GLB_ROOT_PART_NUM}"
  log "GLB_ROOT_DEV=[$GLB_ROOT_DEV]"
  log "GLB_ROOT_PART=[$GLB_ROOT_PART]"
  log "GLB_ROOT_DISK=[$GLB_ROOT_DISK]"
  log "GLB_ROOT_PART_NUM=[$GLB_ROOT_PART_NUM]"
}

# simple resize root partition
function simple_resize_root_partition()
{
  if [ ! -e /etc/rootpt-resize ] \
  && type parted > /dev/null \
  && lock -n /var/lock/root-resize ; then
    if [ x"$GLB_ROOT_DISK" == x ]; then
      log "detect ROOT_DISK device"
      COUNTER=0
      simple_get_root_dev
      while [ "$GLB_ROOT_DISK"x == x ]; do
        sleep 1
        COUNTER=$((COUNTER + 1))
        if [ $COUNTER -gt 29 ]; then
          log "Can't find ROOT_DISK , reboot now"
          force_reboot
        fi
        log "detect ROOT_DISK again"
        simple_get_root_dev
      done
      log "GLB_ROOT_DISK=[$GLB_ROOT_DISK]"
    fi

    if [ x"$GLB_ROOT_DISK" == x ]; then
      log "GLB_ROOT_DISK=[$GLB_ROOT_DISK] is empty, exit now"
      rm -f /var/lock/root-resize
      exit 1
    fi

    # enlarge partition
    log "expand root partition size to full disk device"
    parted -f -s "${GLB_ROOT_DISK}" resizepart "${GLB_ROOT_PART_NUM}" 100%
    sleep 1
    tmpfile=$(mktemp)
    parted "$loop_device" unit MiB print 2>&1 | tee $tmpfile
    log_from_file $tmpfile
    rm -f $tmpfile
    mount_root done
    touch /etc/rootpt-resize
    log "finish expanding root partition size, reboot now"
    force_reboot
  fi
}

# simple resize root filesystem
function simple_resize_root_filesystem()
{
  if [ ! -e /etc/rootfs-resize ] \
  && [ -e /etc/rootpt-resize ] \
  && type losetup > /dev/null \
  && type resize2fs > /dev/null \
  && lock -n /var/lock/root-resize ; then
    if [ x"$GLB_ROOT_DISK" == x ]; then
      log "detect ROOT_DISK device"
      COUNTER=0
      simple_get_root_dev
      while [ "$GLB_ROOT_DISK"x == x ]; do
        sleep 1
        COUNTER=$((COUNTER + 1))
        if [ $COUNTER -gt 29 ]; then
          log "Can't find ROOT_DISK , reboot now"
          force_reboot
        fi
        log "detect ROOT_DISK again"
        simple_get_root_dev
      done
      log "GLB_ROOT_DISK=[$GLB_ROOT_DISK]"
    fi

    if [ x"$GLB_ROOT_DISK" == x ]; then
      log "GLB_ROOT_DISK=[$GLB_ROOT_DISK] is empty, exit now"
      rm -f /var/lock/root-resize
      exit 1
    fi

    # enlarge filesystem
    log "expand root filesystem size to full partition"
    LOOP_DEV="$(awk -e '$5=="/overlay"{print $9}' \
              /proc/self/mountinfo)"
    if [ -z "${LOOP_DEV}" ]; then
      LOOP_DEV="$(losetup -f)"
      losetup "${LOOP_DEV}" "${GLB_ROOT_PART}"
      resize2fs -f "${LOOP_DEV}"
      losetup -d "${LOOP_DEV}"
      sleep 1
      resize2fs -f "${GLB_ROOT_PART}"
    else
      resize2fs -f "${LOOP_DEV}"
    fi
    mount_root done
    touch /etc/rootfs-resize
    log "finish expanding root filesystem size, reboot now"
    force_reboot
  fi
}

# get ROOT device from /proc/cmdline or mount info
function get_root_dev()
{
  local line=$(sed 's/.*root=PARTUUID=\([^ ]*\).*/\1/' /proc/cmdline)
  if [ x"$line" != x ]; then
    root_part=$(blkid | grep $line | cut -d: -f1)
    case "$root_part" in
      "/dev/sd"* )
        GLB_ROOT_DEV=${root_part:0:8}
        GLB_ROOT_PART=$root_part
        GLB_ROOT_PART_NUM="${root_part##*[^0-9]}"
        log "GLB_ROOT_DEV=[$GLB_ROOT_DEV] GLB_ROOT_PART=[$GLB_ROOT_PART]"
        log "GLB_ROOT_PART_NUM=[$GLB_ROOT_PART_NUM]"
        return 0
        ;;
      "/dev/vd"* )
        GLB_ROOT_DEV=${root_part:0:8}
        GLB_ROOT_PART=$root_part
        GLB_ROOT_PART_NUM="${root_part##*[^0-9]}"
        log "GLB_ROOT_DEV=[$GLB_ROOT_DEV] GLB_ROOT_PART=[$GLB_ROOT_PART]"
        log "GLB_ROOT_PART_NUM=[$GLB_ROOT_PART_NUM]"
        return 0
        ;;
      * )
        log "unknown root_part=[$root_part], try mount info"
        #exit 1
        ;;
      esac
  fi

  # try to get root_dev from mount info
  line=$(mount | grep " on / type ")
  if [ x"$line" != x ]; then
    root_part=$(echo $line | awk '{print $1}')
    log "root_part=[$root_part]"
    case "$root_part" in
      "/dev/sd"* )
        GLB_ROOT_DEV=${root_part:0:8}
        GLB_ROOT_PART=$root_part
        GLB_ROOT_PART_NUM="${root_part##*[^0-9]}"
        ;;
      "/dev/vd"* )
        GLB_ROOT_DEV=${root_part:0:8}
        GLB_ROOT_PART=$root_part
        GLB_ROOT_PART_NUM="${root_part##*[^0-9]}"
        ;;
      * )
        log "unknown root_part=[$root_part]"
        exit 1
        ;;
    esac
    log "GLB_ROOT_DEV=[$GLB_ROOT_DEV] GLB_ROOT_PART=[$GLB_ROOT_PART]"
    log "GLB_ROOT_PART_NUM=[$GLB_ROOT_PART_NUM]"
    return 0
  fi

  log "can't get root_dev info"
  exit 1
}

function check_bootstrap_dir()
{
  local bs_dir=$GLB_WORK_DIR/bootstrap
  local up_dir=$GLB_WORK_DIR/upgrade
  local etc_dir=$bs_dir/etc
  local kpcos_file=$etc_dir/kpcos-release

  case "$inst_type" in
    "bootstrap" )
      rm -f $GLB_UPGRADE_FILE
      rm -f $GLB_TESTING_FILE
      rm -rf $up_dir
      ;;
    "upgrade" )
      rm -f $GLB_BOOTSTRAP_FILE
      rm -f $GLB_TESTING_FILE
      rm -rf $bs_dir
      ;;
    "testing" )
      rm -f $GLB_BOOTSTRAP_FILE
      rm -f $GLB_UPGRADE_FILE
      rm -rf $bs_dir
      ;;
    * )
      log "Unknown inst_type=[$inst_type], reboot now!"
      force_reboot
      ;;
  esac

  if [ ! -f $kpcos_file ]; then
    local distro_url="https://gitee.com/m8t/kpcos/raw/master/distro/huangdi"
    local bs_url="${distro_url}/releases/${GLB_HD_VER}/targets/${GLB_OW_TARGET}/bootstrap.tgz"
    local md5_url="${distro_url}/releases/${GLB_HD_VER}/targets/${GLB_OW_TARGET}/bootstrap.tgz.md5"

    if [ "$inst_type" == "upgrade" ]; then
      bs_url="${distro_url}/releases/${GLB_HD_NEXT_VER}/targets/${GLB_OW_TARGET}/bootstrap.tgz"
      md5_url="${distro_url}/releases/${GLB_HD_NEXT_VER}/targets/${GLB_OW_TARGET}/bootstrap.tgz.md5"
    fi
  
    log "bootstrap url=[$bs_url]"
    log "md5file url=[$md5_url]"

    rm -f bootstrap.tgz
    log "curl -o bootstrap.tgz -L $bs_url"
    curl -o bootstrap.tgz -L $bs_url

    rm -f bootstrap.tgz.md5
    log "curl -o bootstrap.tgz.md5 -L $md5_url"
    curl -o bootstrap.tgz.md5 -L $md5_url

    if [ ! -f bootstrap.tgz ]; then
      log "No bootstrap file"
      exit 1
    fi

    if [ ! -f bootstrap.tgz.md5 ]; then
      log "No bootstrap MD5 file"
      exit 1
    fi

    md5_calc=$(md5sum bootstrap.tgz | awk '{print $1}')
    md5_orig=$(cat bootstrap.tgz.md5 | awk '{print $1}')
    if [ x"$md5_calc" != x"$md5_orig" ]; then
      log "Mismatch MD5! orig MD5=[$md5_orig], calc MD5=[$md5_calc]"
      exit 1
    fi

    rm -rf bootstrap/
    tar -zvxf bootstrap.tgz

    local pre_dir=$bs_dir/preinstall
    local dl_file=$pre_dir/download.sh
    local bs_file=$pre_dir/bootstrap_ipks.txt
    local pi_file=$pre_dir/preinstall_ipks.txt

    if [ -f $bs_file ]; then
      log "download bootstrap ipks"
      $dl_file "$bs_file"
    else
      bs_file=$pre_dir/bootstrap_apks.txt
      if [ -f $bs_file ]; then
        log "download bootstrap apks"
        $dl_file "$bs_file"
      else
        log "don't need to download bootstrap pkgs!"
      fi
    fi

    if [ -f $pi_file ]; then
      log "download preinstall ipks"
      $dl_file "$pi_file"
    else
      pi_file=$pre_dir/preinstall_apks.txt
      if [ -f $pi_file ]; then
        log "download preinstall apks"
        $dl_file "$pi_file"
      else
        log "don't need to download preinstall pkgs!"
      fi
    fi

    log "cp -af $etc_dir/* /etc/"
    #cp -af $etc_dir/* /etc/
    for file in $(ls -A $etc_dir/); do
      cp -af "$etc_dir/$file" /etc/
    done

    #log "cp -af $bs_dir/lib/systemd/* /lib/systemd/"
    #cp -af $bs_dir/lib/systemd/* /lib/systemd/
    #for file in $(ls -A $bs_dir/lib/systemd/); do
    #  cp -af "$bs_dir/lib/systemd/$file" /lib/systemd/
    #done

    log "cp -af $bs_dir/usr/sbin/* /usr/sbin/"
    #cp -af $bs_dir/usr/sbin/* /usr/sbin/
    for file in $(ls -A $bs_dir/usr/sbin/); do
      cp -af "$bs_dir/usr/sbin/$file" /usr/sbin/
    done

    local conf_file=/etc/kpc/bootstrap.conf
    local conf_file_def=$GLB_WORK_DIR/bootstrap.conf
    local conf_file_qemu=$etc_dir/kpc/bootstrap.conf.qemu
    if [ ! -f $conf_file ]; then
      if [ -f $conf_file_def ]; then
        log "mv -f $conf_file_def $conf_file"
        mv -f $conf_file_def $conf_file
      elif [ -f $conf_file_qemu ]; then
        log "cp -f $conf_file_qemu $conf_file"
        cp -f $conf_file_qemu $conf_file
      else
        log "No bootstrap.conf candidate"
      fi
    fi

    case "$inst_type" in
      "bootstrap" )
        if [ "$GLB_REAL_PATH" != "$GLB_BOOTSTRAP_FILE" ]; then
          curl -o bootstrap.sh -L $distro_url/bootstrap.sh
          cp -f bootstrap.sh $GLB_BOOTSTRAP_FILE
	  chmod a+x $GLB_BOOTSTRAP_FILE
	  $GLB_BOOTSTRAP_FILE
	  exit 1
        fi
        ;;
      "upgrade" )
        if [ "$GLB_REAL_PATH" != "$GLB_UPGRADE_FILE" ]; then
          curl -o upgrade.sh -L $distro_url/upgrade.sh
          cp -f upgrade.sh $GLB_UPGRADE_FILE
	  chmod a+x $GLB_UPGRADE_FILE
	  $GLB_UPGRADE_FILE
	  exit 1
        fi
        ;;
      "testing" )
        if [ "$GLB_REAL_PATH" != "$GLB_TESTING_FILE" ]; then
          curl -o testing.sh -L $distro_url/testing.sh
          cp -f testing.sh $GLB_TESTING_FILE
	  chmod a+x $GLB_TESTING_FILE
	  $GLB_TESTING_FILE
	  exit 1
        fi
        ;;
      * )
        log "Unknown inst_type=[$inst_type], exit now!"
	exit 1
        ;;
    esac
  fi
}

# start kpc-heartbeat
function start_heartbeat()
{
  heartbeat_conf_dir=/etc/kpc
  heartbeat_conf_file=/etc/kpc/heartbeat.conf
  heartbeat_file=/usr/sbin/kpc-heartbeat.sh
  heartbeat_lock=/tmp/kpc-hearbeat.lock
  if [ ! -f $heartbeat_conf_file ]; then
    mkdir -p $heartbeat_conf_dir
    echo 9 >$heartbeat_conf_file
  fi
  if [ -x $heartbeat_file ]; then
    log "start kpc-heartbeat"
    (flock -n $heartbeat_lock -c "($heartbeat_file)")&
  fi
}

# set dpkg install in a non-interactive mode
function set_opkg_install_noninteractive()
{
  local name="$@"
  case "$name" in
    "firmware-ipw2x00" )
      #echo firmware-ipw2x00 firmware-ipw2x00/license/accepted boolean true | debconf-set-selections
      ;;
    "firmware-ivtv" )
      #echo firmware-ivtv firmware-ivtv/license/accepted boolean true | debconf-set-selections
      ;;
    "firmware-iwlwifi" )
      #echo firmware-iwlwifi firmware-iwlwifi/license/accepted boolean true | debconf-set-selections
      ;;
    * )
      log "nothing to do with package [$name] for non-interactive installation"
      ;;
  esac
}

# list all installed packages
function prepare_installed_pkgs()
{
  tmpfile=$(mktemp)
  opkg list-installed >$tmpfile
  declare_i_arr lists
  while IFS= read -r line;
  do
    add_i_arr_el lists "$line"
  done <$tmpfile
  rm -f $tmpfile

  log "=== installed packages list ==="
  local i=0
  get_i_arr_indices lists indices
  for i in $indices
  do
    get_i_arr_val lists $i line
    #log "line=[${line}]"
    local pkg_name=$(echo "${line}" | awk '{print $1}')
    add_i_arr_el GLB_INSTALLED_PKGS "$pkg_name"
  done
  log "=== end of installed packages list ==="
  get_i_arr_el_cnt GLB_INSTALLED_PKGS GLB_NUM_INSTALLED_PKGS
  log "GLB_NUM_INSTALLED_PKGS=[$GLB_NUM_INSTALLED_PKGS]"
}

# install bootstrap packages for manipulate partitions
function install_bootstrap_pkgs()
{
  local pre_dir=$GLB_WORK_DIR/bootstrap/preinstall
  local pkgs_file=$pre_dir/bootstrap_ipks.txt
  if [ -f $pkgs_file ]; then
    log "bootstrap ipks file is [$pkgs_file]"
  else
    pkgs_file=$pre_dir/bootstrap_apks.txt
    if [ -f $pkgs_file ]; then
      log "bootstrap apks file is [$pkgs_file]"
    else
      log "no bootstrap pkgs list file!"
      return 1
    fi
  fi
  if [ -f $pkgs_file ]; then
    declare_i_arr lists
    while IFS= read -r line;
    do
      add_i_arr_el lists "$line"
    done <$pkgs_file

    local i=0
    get_i_arr_indices lists indices
    for i in $indices
    do
      get_i_arr_val lists $i line
      #log "lists[$i]=[${line}]"
      local name=$(echo ${line} | awk '{print $1}')
      local url=$(echo ${line} | awk '{print $2}')
      #log "name=[$name] url=[$url]"

      local matched="no"
      #log "before matched=[$matched]"
      for line2 in $GLB_INSTALLED_PKGS
      do
        #log "line2=[$line2]"
        if [ "${line2}" == "$name" ]; then
          #log "package $name is in installed list"
          matched="yes"
          break;
        fi
      done
      #log "after matched=[$matched]"
      if [ "$matched" == "yes" ]; then
        continue
      fi

      case "$name" in
        "#"* )
          #log "it's comment"
          ;;
        "" )
          #log "it's empty line"
          ;;
        * )
          #log "name=[$name]"
          local filename="${url##*/}"
          if [ "${filename}" != "" ]; then
            local md5_file=${pre_dir}/${name}.md5
            if [ ! -f $md5_file ]; then
              log "no $md5_file, continue"
              continue
            fi
            local md5_orig=$(cat $md5_file)
            local md5_calc=$(md5sum $pre_dir/$filename | awk '{print $1}')
            if [ "$md5_orig" == "$md5_calc" ]; then
              log "set [$name] to non-interactive mode"
              set_opkg_install_noninteractive $name
              log "opkg install $pre_dir/$filename"
              opkg install $pre_dir/$filename
              line=$(opkg status $name | grep "Package: $name")
              if [ "$line" == "Package: $name" ]; then
                #GLB_INSTALLED_PKGS[$GLB_NUM_INSTALLED_PKGS]="$name"
                add_i_arr_el GLB_INSTALLED_PKGS "$name"
                get_i_arr_el_cnt GLB_INSTALLED_PKGS GLB_NUM_INSTALLED_PKGS
                log "rm -f $md5_file"
                rm -f $md5_file
              fi
            else
              log "MD5 mismatch, skip $name"
            fi
          fi
          ;;
      esac
    done
  fi
}

function detect_root_dev()
{
  local test_dev=$1
  log "detect root dev $test_dev"

  if [ "${test_dev}"x == x ]; then
    log "Error: test_dev is empty!!!"
    return 1
  fi

  local kpcos_release_file=/mnt/etc/kpcos-release
  local openwrt_release_file=/mnt/etc/openwrt_release
  for i in $(seq 4)
  do
    local part_dev="${test_dev}${i}"
    if [ -e $part_dev ]; then
      mount $part_dev /mnt
      if [ ! -f $kpcos_release_file ]; then
        log "No file $kpcos_release_file , return now"
        umount /mnt
        continue
      fi
      if [ "$(grep 'ID="huangdi"' $kpcos_release_file)" != 'ID="huangdi"' ]; then
        log "Not HuangDi release, return now"
        umount /mnt
        return 1
      fi
      if [ -f $openwrt_release_file ]; then
        ow_ver=$(get_openwrt_version_string $openwrt_release_file)
        log "ow_ver is [$ow_ver]"

        case "$ow_ver" in
          "$GLB_OW_VER" )
            GLB_ROOT_DEV="$test_dev"
            GLB_ROOT_PART="$part_dev"
            GLB_ROOT_DISK="$GLB_ROOT_DEV"
            GLB_ROOT_PART_NUM="$i"
            /usr/sbin/kpc-sync-kpcos-release /mnt
            umount /mnt
            return 0
            ;;
          * )
            log "Unknown OpenWrt Version [$ow_ver]"
            ;;
        esac
      fi
      umount /mnt
    fi
  done

  return 1
}

function detect_all_root_devs()
{
  root_devs="
    /dev/vda /dev/vdb /dev/vdc /dev/vdd
    /dev/sda /dev/sdb /dev/sdc /dev/sdd
  "

  for root_dev in "${root_devs}"
  do
    detect_root_dev "${root_dev}"
    if [ "$GLB_ROOT_DEV"x != x ]; then
      log "find ROOT_DEV=[$GLB_ROOT_DEV] ROOT_PART=[$GLB_ROOT_PART]"
      return 0
    fi
  done
}

# resize root partition
function resize_root_partition()
{
  if [ x"$GLB_ROOT_DEV" == x ]; then
    log "detect ROOT_DEV device"
    COUNTER=0
    detect_all_root_devs
    while [ "$GLB_ROOT_DEV"x == x ]; do
      sleep 1
      COUNTER=$((COUNTER + 1))
      if [ $COUNTER -gt 29 ]; then
        log "Can't find ROOT_DEV , reboot now"
        force_reboot
      fi
      log "detect ROOT_DEV again"
      detect_all_root_devs
    done
    log "GLB_ROOT_DEV=[$GLB_ROOT_DEV]"
  fi

  if [ x"$GLB_ROOT_DEV" == x ]; then
    log "GLB_ROOT_DEV=[$GLB_ROOT_DEV] is empty, exit now"
    exit 1
  fi

  line=$(df -m | grep "^${GLB_ROOT_PART} ")
  if [ x"$line" == x ]; then
    line=$(df -m | grep "^/dev/root ")
    if [ x"$line" == x ]; then
      log "can't get root dev partition info"
      exit 1
    fi
  fi
  orig_size=$(echo $line | awk '{print $2}')
  orig_mpoint=$(echo $line | awk '{print $6}')
  log "original dev=[$GLB_ROOT_PART] size=[$orig_size] mpoint=[$orig_mpoint]"

  # enlarge partition
  log "extend root partition size to full disk device"
  export loop_device=$(losetup -f)
  losetup $loop_device $GLB_ROOT_DEV
  sleep 1
  echo -e "Fix" | parted ---pretend-input-tty "$loop_device" print
  sleep 1
  parted -f -s "$loop_device" resizepart "${GLB_ROOT_PART_NUM}" 100%
  sleep 1
  tmpfile=$(mktemp)
  parted "$loop_device" unit MiB print 2>&1 | tee $tmpfile
  log_from_file $tmpfile
  rm -f $tmpfile

  # check if root partition space is enough
  line=$(df -m | grep "^${GLB_ROOT_PART} ")
  if [ x"$line" == x ]; then
    line=$(df -m | grep "^/dev/root ")
    if [ x"$line" == x ]; then
      log "can't get root dev partition info"
      exit 1
    fi
  fi
  size=$(echo $line | awk '{print $2}')
  mpoint=$(echo $line | awk '{print $6}')
  log "original dev=[$GLB_ROOT_PART] size=[$size] mpoint=[$mpoint]"

  if [ ${size%?} -lt 4000 ]; then
    log "root partition space is less than 4GB"
    if [ "$orig_size" == "$size" ]; then
      log "root partition file system not resized!"
      loop_device=$(losetup -f)
      losetup $loop_device $GLB_ROOT_PART
      sleep 1
      resize2fs -f $loop_device
      sleep 1
      tmpfile=$(mktemp)
      df -m 2>&1 | tee $tmpfile
      log_from_file $tmpfile
      rm -f $tmpfile
      losetup -d $loop_device
      # check size again
      line=$(df -m | grep "^${GLB_ROOT_PART} ")
      size=$(echo $line | awk '{print $2}')
      mpoint=$(echo $line | awk '{print $6}')
      log "$line"
      if [ ${size%?} -lt 4000 ]; then
        log "root partition space is still less than 4GB, reboot now"
        force_reboot
        #exit 1
      fi
    else
      log "root partition resized, but it's not enough space!"
      exit 1
    fi
  fi
}

# preinstall packages for networking
function preinstall_pkgs()
{
  local pre_dir=$GLB_WORK_DIR/bootstrap/preinstall
  local pkgs_file=$pre_dir/preinstall_ipks.txt
  if [ -f $pkgs_file ]; then
    log "preinstall ipks file is [$pkgs_file]"
  else
    pkgs_file=$pre_dir/preinstall_apks.txt
    if [ -f $pkgs_file ]; then
      log "preinstall apks file is [$pkgs_file]"
    else
      log "no preinstall pkgs list file!"
      return 1
    fi
  fi
  if [ -f $pkgs_file ]; then
    declare_i_arr lists
    while IFS= read -r line;
    do
      add_i_arr_el lists "$line"
    done <$pkgs_file

    local i=0
    get_i_arr_indices lists indices
    for i in $indices
    do
      get_i_arr_val lists $i line
      #log "lists[$i]=[${line}]"
      local name=$(echo ${line} | awk '{print $1}')
      local url=$(echo ${line} | awk '{print $2}')
      #log "name=[$name] url=[$url]"

      local matched="no"
      #log "before matched=[$matched]"
      for line2 in $GLB_INSTALLED_PKGS
      do
        #log "line2=[$line2]"
        if [ "${line2}" == "$name" ]; then
          #log "package $name is in installed list"
          matched="yes"
          break;
        fi
      done
      #log "after matched=[$matched]"
      if [ "$matched" == "yes" ]; then
        continue
      fi

      case "$name" in
        "#"* )
          #log "it's comment"
          ;;
        "" )
          #log "it's empty line"
          ;;
        * )
          #log "name=[$name]"
          local filename="${url##*/}"
          if [ "${filename}" != "" ]; then
            local md5_file=${pre_dir}/${name}.md5
            if [ ! -f $md5_file ]; then
              log "no $md5_file, continue"
              continue
            fi
            local md5_orig=$(cat $md5_file)
            local md5_calc=$(md5sum $pre_dir/$filename | awk '{print $1}')
            if [ "$md5_orig" == "$md5_calc" ]; then
              log "set [$name] to non-interactive mode"
              set_opkg_install_noninteractive $name
              log "opkg install $pre_dir/$filename"
              opkg install $pre_dir/$filename
              line=$(opkg status $name | grep "Package: $name")
              if [ "$line" == "Package: $name" ]; then
                #GLB_INSTALLED_PKGS[$GLB_NUM_INSTALLED_PKGS]="$name"
                add_i_arr_el GLB_INSTALLED_PKGS "$name"
                get_i_arr_el_cnt GLB_INSTALLED_PKGS GLB_NUM_INSTALLED_PKGS
                log "rm -f $md5_file"
                rm -f $md5_file
              fi
            else
              log "MD5 mismatch, skip $name"
            fi
          fi
          ;;
      esac
    done
  fi
}

# run bootstrap configurating
function run_bootstrap_config()
{
  local wifi_backend=""
  local wifi_dev=""
  local wifi_addr=""
  local wifi_mode=""
  local wifi_net=""
  local wifi_pass=""

  local conf_file=/etc/kpc/bootstrap.conf
  if [ -f $conf_file ]; then
    log "start to configurate bootstrap environment"

    declare_i_arr lists
    while IFS= read -r line;
    do
      add_i_arr_el lists "$line"
    done <$conf_file

    local i=0
    get_i_arr_indices lists indices
    for i in $indices
    do
      get_i_arr_val lists $i line
      #log "lists[$i]=[${line}]"
      local name=$(echo ${line} | awk '{print $1}')
      local val=$(echo ${line} | awk '{print $2}')
      #log "name=[$name] val=[$val]"
      case "$name" in
        "#"* )
          #log "it's comment"
          ;;
        "" )
          #log "it's empty line"
          ;;
        "wifi.backend" )
          if [ "$val" == "iwd" ]; then
            log "enable iwd network configuration"
            wifi_backend="$val"
            iwd_main_conf=/etc/iwd/main.conf
            sed "s/#EnableNetworkConfiguration=true/EnableNetworkConfiguration=true/g" -i $iwd_main_conf
            #log_from_file $iwd_main_conf
          fi
          ;;
        "wifi.device_name" )
          wifi_dev="$val"
          log "wifi_dev=[$wifi_dev]"
          ;;
        "wifi.device_address" )
          wifi_addr="$val"
          log "wifi_addr=[$wifi_addr]"
          ;;
        "wifi.mode" )
          wifi_mode="$val"
          log "wifi_mode=[$wifi_mode]"
          ;;
        "wifi.network" )
          wifi_net="$val"
          log "wifi_net=[$wifi_net]"
          ;;
        "wifi.passphrase" )
          wifi_pass="$val"
          log "wifi_pass=[$wifi_pass]"
          ;;
        * )
          log "unknown option=[$name]"
          ;;
      esac
    done

    if [ "$wifi_backend" == "iwd" ]; then
      log "systemctl --now enable iwd"
      systemctl --now enable iwd
      sleep 3
      if [ x"$wifi_dev" == x ]; then
        #iwctl device list
        line=$(iwctl device list | grep "station" )
        log "line=[$line]"
        if [ x"$line" == x ]; then
          log "no station mode wifi device found, exit now"
          exit 1
        fi
        #dummy=$(echo $line | awk '{print $1}')
        dummy=$(echo $line | awk '{print $1}')
        log "dummy=[$dummy]"
        #dev_name=$(echo $line | awk '{print $2}')
        wifi_dev=$(echo $line | awk '{print $2}')
        log "wifi_dev=[$wifi_dev]"
        #dev_addr=$(echo $line | awk '{print $3}')
        wifi_addr=$(echo $line | awk '{print $3}')
        log "wifi_addr=[$wifi_addr]"
        #dev_powered=$(echo $line | awk '{print $4}')
        wifi_powered=$(echo $line | awk '{print $4}')
        log "wifi_powered=[$wifi_powered]"
        #dev_adapter=$(echo $line | awk '{print $5}')
        wifi_adapter=$(echo $line | awk '{print $5}')
        log "wifi_adapter=[$wifi_adapter]"
        #dev_mode=$(echo $line | awk '{print $6}')
        wifi_mode=$(echo $line | awk '{print $6}')
        log "wifi_mode=[$wifi_mode]"

        log "detect wifi_dev=[$wifi_dev]"
        if [ x"$wifi_dev" == x ]; then
          log "no wifi device found, exit now"
          exit 1
        fi
      fi
      if [ x"$wifi_dev" != x ]; then
        line=$(iwctl device list | grep " $wifi_dev " )
        log "line=[$line]"
        if [ x"$line" != x ]; then
          dummy=$(echo $line | awk '{print $1}')
          dev_name=$(echo $line | awk '{print $2}')
          dev_addr=$(echo $line | awk '{print $3}')
          dev_powered=$(echo $line | awk '{print $4}')
          dev_adapter=$(echo $line | awk '{print $5}')
          dev_mode=$(echo $line | awk '{print $6}')
          log "dev_mode=[$dev_mode]"
          if [ "$dev_mode" == "station" ]; then
            #iwctl station wlan0 scan
            tmpfile=$(mktemp)
            iwctl station $wifi_dev scan 2>&1 | tee $tmpfile
            log_from_file $tmpfile
            rm -f $tmpfile
            sleep 3

            #iwctl station wlan0 get-networks
            tmpfile=$(mktemp)
            iwctl station $wifi_dev get-networks 2>&1 | tee $tmpfile
            log_from_file $tmpfile
            rm -f $tmpfile

            #iwctl --passphrase "mysecret" station wlan0 connect "SSID"
            log "iwctl --passphrase $wifi_pass station $wifi_dev connect $wifi_net"
            iwctl --passphrase "$wifi_pass" station $wifi_dev connect "$wifi_net"
            sleep 3

            #iwctl station wlan0 show
            tmpfile=$(mktemp)
            iwctl station $wifi_dev show 2>&1 | tee $tmpfile
            log_from_file $tmpfile
            rm -f $tmpfile
            log "/etc/init.d/iwd restart"
            /etc/init.d/iwd restart
            sleep 1
          fi
        fi
      fi
      #iwctl station wlan0 scan
      #iwctl station wlan0 get-networks
      #iwctl --passphrase "mysecret" station wlan0 connect "SSID"
      #iwctl station wlan0 show
      #/etc/init.d/iwd restart
      #iwctl station wlan0 disconnect
    fi #endof wifi_backend==iwd
  fi
}

# check WAN interface
function check_wan_iface()
{
  local COUNTER=0
  local dev_array="$(ip route | awk '/default/ {print $5}')"
  local iface_dev=$(echo $dev_array | awk '{print $1}')
  while [ "$iface_dev"x == x ]; do
    sleep 1
    COUNTER=$((COUNTER + 1))
    if [ $COUNTER -gt 29 ]; then
      log "Can't get default route device interface, exit now"
      exit 1
    fi
    dev_array="$(ip route | awk '/default/ {print $5}')"
    iface_dev=$(echo $dev_array | awk '{print $1}')
  done

  COUNTER=0
  local WAN_IP=$(ip addr show $iface_dev | grep "inet" | head -n 1 | awk '/inet/ {print $2}' | cut -d'/' -f1)
  while [ "${WAN_IP}"x == x ]; do
    sleep 1
    COUNTER=$((COUNTER + 1))
    if [ $COUNTER -gt 29 ]; then
      log "Can't get WAN IP address, reboot now"
      force_reboot
    fi
    WAN_IP=$(ip addr show $iface_dev | grep "inet" | head -n 1 | awk '/inet/ {print $2}' | cut -d'/' -f1)
  done
  log "WAN IP=[${WAN_IP}]"
}

function get_upgrade_file()
{
  local distro_url="https://gitee.com/m8t/kpcos/raw/master/distro/huangdi"
  local up_url="${distro_url}/releases/${GLB_HD_VER}/targets/${GLB_OW_TARGET}/upgrade.tgz"
  local md5_url="${distro_url}/releases/${GLB_HD_VER}/targets/${GLB_OW_TARGET}/upgrade.tgz.md5"

  if [ "$inst_type" == "upgrade" ]; then
    up_url="${distro_url}/releases/${GLB_HD_NEXT_VER}/targets/${GLB_OW_TARGET}/upgrade.tgz"
    md5_url="${distro_url}/releases/${GLB_HD_NEXT_VER}/targets/${GLB_OW_TARGET}/upgrade.tgz.md5"
  fi
  
  log "upgrade url=[$up_url]"
  log "md5file url=[$md5_url]"

  rm -f upgrade.tgz
  log "curl -o upgrade.tgz -L $up_url"
  curl -o upgrade.tgz -L $up_url

  rm -f upgrade.tgz.md5
  log "curl -o upgrade.tgz.md5 -L $md5_url"
  curl -o upgrade.tgz.md5 -L $md5_url

  if [ ! -f upgrade.tgz ]; then
    log "No upgrade file"
    force_reboot
  fi

  if [ ! -f upgrade.tgz.md5 ]; then
    log "No upgrade MD5 file"
    force_reboot
  fi

  md5_calc=$(md5sum upgrade.tgz | awk '{print $1}')
  md5_orig=$(cat upgrade.tgz.md5 | awk '{print $1}')
  if [ x"$md5_calc" != x"$md5_orig" ]; then
    log "Mismatch MD5! orig MD5=[$md5_orig], calc MD5=[$md5_calc]"
    force_reboot
  fi
}

function run_first_boot()
{
  local firstboot_dir=/etc/kpc/firstboot
  local firstboot_file=$firstboot_dir/guest/huangdi-first-boot.sh

  # unpack upgrade file
  rm -rf upgrade/
  tar -zvxf upgrade.tgz

  # rename work dir
  mkdir -p /etc/kpc
  rm -rf $firstboot_dir
  mv -f upgrade $firstboot_dir

  if [ ! -f $firstboot_file ]; then
    log "No first boot script"
    rm -rf $firstboot_dir
    force_reboot
  fi

  if [ -x $firstboot_file ]; then
    log "start first boot script"
    touch "$GLB_DONE_FILE"
    reset_reboot_counter
    $firstboot_file
  else
    log "first boot script is not executive"
    rm -rf $firstboot_dir
    force_reboot
  fi

  # remove work dir
  # FIXME: don't remove
  #rm -rf firstboot/
}

function run_sys_upgrade()
{
  local sysupgrade_dir=/etc/kpc/sysupgrade
  local sysupgrade_file=$sysupgrade_dir/guest/huangdi-sys-upgrade.sh

  # unpack upgrade file
  rm -rf upgrade/
  tar -zvxf upgrade.tgz

  # rename work dir
  mkdir -p /etc/kpc
  rm -rf $sysupgrade_dir
  mv -f upgrade $sysupgrade_dir

  if [ ! -f $sysupgrade_file ]; then
    log "No system upgrade script"
    rm -rf $sysupgrade_dir
    #force_reboot
    exit 1
  fi

  if [ -x $sysupgrade_file ]; then
    log "start system upgrade script"
    touch "$GLB_DONE_FILE"
    reset_reboot_counter
    $sysupgrade_file
  else
    log "system upgrade script is not executive"
    rm -rf $sysupgrade_dir
    #force_reboot
    exit 1
  fi

  # remove work dir
  # FIXME: don't remove
  #rm -rf upgrade/
}

# start script
log_init
fix_possible_broken
get_work_dir
log "cd $GLB_WORK_DIR"
cd "$GLB_WORK_DIR"
check_reboot_counter
save_pkg_list pre_${inst_type}_pkgs.txt

detect_cpu_arch
find_openwrt_version /etc/openwrt_release
verify_upgrade_version
#get_root_dev
simple_get_root_dev

case "$inst_type" in
  bootstrap )
    check_bootstrap_dir
    start_heartbeat

    prepare_installed_pkgs
    install_bootstrap_pkgs
    #resize_root_partition
    simple_resize_root_partition
    simple_resize_root_filesystem
    preinstall_pkgs
    run_bootstrap_config

    check_wan_iface
    get_upgrade_file

    save_pkg_list post_${inst_type}_pkgs.txt
    run_first_boot
    ;;

  upgrade )
    #check_bootstrap_dir
    start_heartbeat

    check_wan_iface
    get_upgrade_file

    save_pkg_list post_${inst_type}_pkgs.txt
    run_sys_upgrade
    ;;

  testing )
    #check_bootstrap_dir
    start_heartbeat

    check_wan_iface
    get_upgrade_file

    save_pkg_list post_${inst_type}_pkgs.txt
    run_sys_upgrade
    ;;

  * )
    log "install type is [$inst_tyep], do nothing"
    ;;
esac

exit 0
